Learn in 10 minutes

Learn in 10 minutes

10 मिनट में Python सीखें

Python एक उच्च-स्तरीय, व्याख्यात्मक प्रोग्रामिंग भाषा है, जो अपने संक्षिप्त सिंटेक्स और शक्तिशाली सुविधाओं के लिए जानी जाती है। यह ट्यूटोरियल नवीनतम Python 3.13+ संस्करण पर आधारित है, जो आपको जल्दी से Python सीखने में मदद करता है।

1. अपना पहला Python प्रोग्राम लिखना

आइए एक साधारण प्रोग्राम के साथ शुरू करें। hello.py नाम की एक फ़ाइल बनाएँ और निम्नलिखित कोड दर्ज करें:

print("Hello, World!")

फ़ाइल को सहेजें और टर्मिनल या कमांड लाइन में निम्नलिखित कमांड चलाएँ:

python hello.py

आउटपुट होगा:

Hello, World!

यह साधारण प्रोग्राम Python की मूल आउटपुट कार्यक्षमता को दर्शाता है। print() फ़ंक्शन का उपयोग कंसोल में पाठ जानकारी प्रदर्शित करने के लिए किया जाता है।

2. मूल सिंटेक्स

Python का सिंटेक्स सरल और समझने में आसान है। Python कोड ब्लॉक्स को परिभाषित करने के लिए इंडेंटेशन का उपयोग करता है, न कि अन्य भाषाओं की तरह घुंघराले ब्रेस {} का।

# यह एक टिप्पणी है
print("Hello, World!")

Python में मूल सिंटेक्स नियम:

  • इंडेंटेशन: डिफ़ॉल्ट रूप से, 4 रिक्त स्थान एक कोड ब्लॉक के स्तर को दर्शाने के लिए उपयोग किए जाते हैं। उदाहरण के लिए, फ़ंक्शंस या लूप्स के अंदर का कोड इंडेंटेड होना चाहिए।
  • टिप्पणियाँ: एकल-पंक्ति टिप्पणियाँ # से शुरू होती हैं, जबकि बहु-पंक्ति टिप्पणियाँ ट्रिपल कोट्स """ या ''' का उपयोग करती हैं।
  • कथन: आमतौर पर प्रति पंक्ति एक कथन, अंत में सेमीकॉलन ; की आवश्यकता नहीं होती।
  • कोड ब्लॉक्स: इंडेंटेशन द्वारा परिभाषित, जैसे if, for, या फ़ंक्शन बॉडी।

बहु-पंक्ति टिप्पणियों का उदाहरण:

"""
यह एक बहु-पंक्ति टिप्पणी है,
जो कई पंक्तियों तक फैली हुई है।
"""

इंडेंटेशन Python के सिंटेक्स की एक प्रमुख विशेषता है, जिसका उपयोग कोड ब्लॉक्स की संरचना को परिभाषित करने के लिए किया जाता है:

if True:
    print("यह पंक्ति इंडेंटेड है")
    print("यह पंक्ति भी इंडेंटेड है")
print("यह पंक्ति इंडेंटेड नहीं है")

3. वेरिएबल्स और डेटा प्रकार

Python में, वेरिएबल्स डेटा संग्रह करने के लिए कंटेनर हैं। Python एक गतिशील रूप से टाइप की गई भाषा है, जिसका अर्थ है कि आपको वेरिएबल के प्रकार को पहले से घोषित करने की आवश्यकता नहीं है।

वेरिएबल नामकरण के मूल नियम:

  • वेरिएबल नामों में केवल अक्षर, संख्या और अंडरस्कोर शामिल हो सकते हैं।
  • वेरिएबल नाम संख्या से शुरू नहीं हो सकते।
  • वेरिएबल नाम केस-संवेदनशील हैं।
  • Python के कीवर्ड्स को वेरिएबल नामों के रूप में उपयोग नहीं किया जा सकता।

वेरिएबल प्रकार असाइन किए गए मान से निर्धारित होते हैं। Python के मुख्य मूल डेटा प्रकार हैं:

  • इंटीजर (int): उदाहरण के लिए, 42 या -10, कोई आकार सीमा नहीं।
  • फ्लोट (float): उदाहरण के लिए, 3.14 या 2.5e3 (वैज्ञानिक संकेतन)।
  • स्ट्रिंग (str): उदाहरण के लिए, "hello" या 'world', एकल या दोहरे कोट्स का उपयोग।
  • बूलियन (bool): True या False
  • NoneType (None): None द्वारा दर्शाया जाता है, जो नल या कोई मान नहीं होने को दर्शाता है।

Python कोड की पठनीयता बढ़ाने के लिए टाइप हिन्ट्स का समर्थन करता है, जो स्थिर जाँच और IDE समर्थन के लिए उपयोग किया जाता है, बिना रनटाइम व्यवहार को प्रभावित किए:

name: str = "Alice"
age: int = 25

3.1 संख्यात्मक प्रकार (Number)

Python तीन संख्यात्मक प्रकारों का समर्थन करता है: इंटीजर (int), फ्लोट (float), और कॉम्प्लेक्स (complex)।

# इंटीजर
age = 25
population = 1000000

# फ्लोट
temperature = 36.5
pi = 3.14159

# कॉम्प्लेक्स
complex_num = 3 + 4j

3.2 स्ट्रिंग (String)

स्ट्रिंग्स वर्णों का अनुक्रम हैं, जो एकल या दोहरे कोट्स में संलग्न होते हैं।

single_quote = 'एकल कोट स्ट्रिंग'
double_quote = "दोहरा कोट स्ट्रिंग"
multiline = """यह एक
बहु-पंक्ति स्ट्रिंग है"""

स्ट्रिंग ऑपरेशन्स:

text = "Python प्रोग्रामिंग"
print(len(text))        # स्ट्रिंग की लंबाई
print(text.upper())     # अपरकेस में परिवर्तन
print(text.lower())     # लोअरकेस में परिवर्तन
print(text[0])          # पहला वर्ण
print(text[2:6])        # स्ट्रिंग स्लाइसिंग

3.3 बूलियन प्रकार (Boolean)

बूलियन प्रकार के दो मान हैं: True और False

is_active = True
is_complete = False

# बूलियन ऑपरेशन्स
result1 = True and False  # False
result2 = True or False   # True
result3 = not True        # False

3.4 None प्रकार (None)

None नल या कोई मान नहीं होने की स्थिति को दर्शाता है।

value = None

if value is None:
    print("मान नल है")

4. डेटा संरचनाएँ

Python डेटा को संग्रह करने और हेरफेर करने के लिए कई अंतर्निहित डेटा संरचनाएँ प्रदान करता है। नीचे सामान्य रूप से उपयोग की जाने वाली डेटा संरचनाएँ और उनका उपयोग दिया गया है।

4.1 लिस्ट (List)

लिस्ट एक क्रमबद्ध और परिवर्तनीय संग्रह है। आप लिस्ट में तत्व जोड़, हटा या संशोधित कर सकते हैं। लिस्ट को वर्गाकार कोष्ठक [] का उपयोग करके परिभाषित किया जाता है।

numbers = [1, 2, 3, 4, 5]
numbers.append(6)      # तत्व जोड़ें
numbers.insert(0, 0)   # विशिष्ट स्थिति पर डालें
numbers.remove(3)      # विशिष्ट मान हटाएँ
numbers[0] = 10        # तत्व संशोधित करें
print(numbers)         # [10, 2, 4, 5, 6]

सबलिस्ट तक पहुँचने के लिए लिस्ट स्लाइसिंग:

numbers = [10, 20, 30, 40, 50]
print(numbers[1:4])    # आउटपुट: [20, 30, 40]
print(numbers[:3])     # आउटपुट: [10, 20, 30]
print(numbers[-2:])    # आउटपुट: [40, 50]

लिस्ट कॉम्प्रिहेंशन:

squares = [x**2 for x in range(5)]
print(squares)         # [0, 1, 4, 9, 16]

even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares)    # [0, 4, 16, 36, 64]

4.2 टपल (Tuple)

टपल एक क्रमबद्ध लेकिन अपरिवर्तनीय संग्रह है। एक बार बनने के बाद इसके तत्वों को संशोधित नहीं किया जा सकता। टपल को कोष्ठक () का उपयोग करके परिभाषित किया जाता है। उनकी अपरिवर्तनीयता के कारण, टपल आमतौर पर लिस्ट से तेज़ होते हैं और डिक्शनरी कीज़ के रूप में उपयोग किए जा सकते हैं।

point = (10, 20)
x, y = point  # अनपैकिंग
print(x, y)   # आउटपुट: 10 20

एकल-तत्व टपल को कॉमा की आवश्यकता होती है:

single_tuple = (42,)

4.3 डिक्शनरी (Dict)

डिक्शनरी कुंजी-मूल्य जोड़ों का एक अव्यवस्थित (Python 3.7+ में व्यवस्थित) संग्रह है। प्रत्येक कुंजी अद्वितीय होती है और एक मूल्य से संबद्ध होती है। डिक्शनरी को घुंघराले कोष्ठक {} का उपयोग करके परिभाषित किया जाता है।

student = {
    "name": "John",
    "age": 20,
    "major": "Computer Science"
}

# डिक्शनरी तक पहुँचना और संशोधन
print(student["name"])
student["age"] = 21
student["gpa"] = 3.8

# सुरक्षित पहुँच
print(student.get("phone", "प्रदान नहीं किया गया"))

# डिक्शनरी पर पुनरावृत्ति
for key, value in student.items():
    print(f"{key}: {value}")

डिक्शनरी कॉम्प्रिहेंशन:

# वर्ग डिक्शनरी बनाएँ
squares_dict = {x: x**2 for x in range(5)}
print(squares_dict)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# सशर्त डिक्शनरी कॉम्प्रिहेंशन
even_squares_dict = {x: x**2 for x in range(10) if x % 2 == 0}
print(even_squares_dict)  # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

4.4 सेट (Set)

सेट एक अव्यवस्थित संग्रह है जिसमें कोई डुप्लिकेट तत्व नहीं होते। इसे घुंघराले कोष्ठक {} या set() का उपयोग करके परिभाषित किया जाता है।

# सेट बनाना
fruits = {"apple", "banana", "orange"}
numbers = set([1, 2, 3, 3, 4, 4, 5])  # स्वचालित डुप्लिकेशन हटाना
print(numbers)  # {1, 2, 3, 4, 5}

# सेट ऑपरेशन्स
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

print(set1 | set2)  # यूनियन: {1, 2, 3, 4, 5, 6}
print(set1 & set2)  # इंटरसेक्शन: {3, 4}
print(set1 - set2)  # अंतर: {1, 2}
print(set1 ^ set2)  # सममित अंतर: {1, 2, 5, 6}

5. ऑपरेशन्स और ऑपरेटर्स

Python विभिन्न गणनाओं और तुलनाओं के लिए कई ऑपरेटर्स प्रदान करता है, जिनमें अंकगणितीय, तुलना, तार्किक, बिटवाइज़, और पहचान ऑपरेटर्स शामिल हैं।

  • अंकगणितीय ऑपरेटर्स: +, -, *, /, // (पूर्णांक भाग), % (मॉड्यूलस), ** (घातांक)।
  • तुलना ऑपरेटर्स: ==, !=, >, <, >=, <=
  • तार्किक ऑपरेटर्स: and, or, not
  • सदस्यता ऑपरेटर्स: in, not in
  • पहचान ऑपरेटर्स: is, is not

5.1 अंकगणितीय ऑपरेटर्स

अंकगणितीय ऑपरेटर्स गणितीय ऑपरेशन्स के लिए उपयोग किए जाते हैं। ऑपरेटर प्राथमिकता गणितीय नियमों का पालन करती है (उदाहरण के लिए, ** की प्राथमिकता + या - से अधिक है)। प्राथमिकता बदलने के लिए कोष्ठक () का उपयोग किया जा सकता है।

a, b = 10, 3

print(f"जोड़: {a + b}")      # 13
print(f"घटाव: {a - b}")      # 7
print(f"गुणा: {a * b}")      # 30
print(f"भाग: {a / b}")       # 3.333...
print(f"पूर्णांक भाग: {a // b}")  # 3
print(f"मॉड्यूलस: {a % b}")      # 1
print(f"घातांक: {a ** b}")       # 1000

5.2 तुलना ऑपरेटर्स

तुलना ऑपरेटर्स दो मानों की तुलना करते हैं और बूलियन (True या False) लौटाते हैं।

x, y = 5, 10

print(f"बराबर: {x == y}")     # False
print(f"असमान: {x != y}")    # True
print(f"से बड़ा: {x > y}")    # False
print(f"से छोटा: {x < y}")    # True
print(f"बराबर या बड़ा: {x >= y}")  # False
print(f"बराबर या छोटा: {x <= y}")  # True

5.3 तार्किक ऑपरेटर्स

तार्किक ऑपरेटर्स बूलियन मानों (True या False) को जोड़ते या हेरफेर करते हैं, आमतौर पर सशर्त कथनों में उपयोग किए जाते हैं।

a, b = True, False

print(f"AND ऑपरेशन: {a and b}")  # False
print(f"OR ऑपरेशन: {a or b}")    # True
print(f"NOT ऑपरेशन: {not a}")    # False

5.4 पहचान ऑपरेटर्स

is ऑपरेटर दो ऑब्जेक्ट्स की पहचान की तुलना करता है, यह जाँचता है कि क्या वे एक ही मेमोरी पते को संदर्भित करते हैं (न कि केवल बराबर मान)। यह == से भिन्न है, जो सामग्री की तुलना करता है।

list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = list1

print(f"list1 is list2: {list1 is list2}")    # False
print(f"list1 is list3: {list1 is list3}")    # True
print(f"list1 == list2: {list1 == list2}")    # True

5.5 सदस्यता ऑपरेटर्स

सदस्यता ऑपरेटर्स यह जाँचते हैं कि क्या कोई मान किसी अनुक्रम (उदाहरण के लिए, लिस्ट, टपल, स्ट्रिंग, सेट) का सदस्य है, और बूलियन लौटाते हैं।

fruits = ["apple", "banana", "orange"]

print(f"'apple' in fruits: {'apple' in fruits}")        # True
print(f"'grape' not in fruits: {'grape' not in fruits}")  # True

6. नियंत्रण प्रवाह

Python प्रोग्राम के निष्पादन क्रम को प्रबंधित करने के लिए कई नियंत्रण प्रवाह कथन प्रदान करता है।

6.1 if कथन

if कथन एक शर्त का मूल्यांकन करता है और यदि शर्त True है तो इसका ब्लॉक निष्पादित करता है। जटिल शर्तों के लिए elif और else का उपयोग करें।

age = 20
if age >= 18:
    print("वयस्क")
elif age >= 13:
    print("किशोर")
else:
    print("बच्चा")

6.2 for लूप्स

for लूप एक इटेरेबल ऑब्जेक्ट (उदाहरण के लिए, लिस्ट, टपल, स्ट्रिंग, या रेंज) पर पुनरावृत्ति करता है।

# लिस्ट पर पुनरावृत्ति
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

# लूपिंग के लिए range() का उपयोग
for i in range(5):
    print(i)  # आउटपुट: 0, 1, 2, 3, 4

6.3 while लूप्स

while लूप तब तक ब्लॉक निष्पादित करता रहता है जब तक इसकी शर्त True रहती है।

count = 0
while count < 5:
    print(count)
    count += 1
  • break और continue: break लूप से बाहर निकलता है, continue वर्तमान पुनरावृत्ति को छोड़ देता है।
for i in range(10):
    if i == 5:
        break
    if i % 2 == 0:
        continue
    print(i)  # आउटपुट: 1, 3

6.4 match कथन

Python 3.10 में पेश किया गया, match कथन शक्तिशाली संरचनात्मक पैटर्न मिलान प्रदान करता है, जो if/elif/else श्रृंखलाओं का एक उन्नत विकल्प है।

http_status = 200

match http_status:
    case 200 | 201:
        print("सफलता")
    case 404:
        print("नहीं मिला")
    case 500:
        print("सर्वर त्रुटि")
    case _:  # वाइल्डकार्ड, किसी अन्य मामले से मेल खाता है
        print("अज्ञात स्थिति")

7. इनपुट और आउटपुट

7.1 मूल इनपुट और आउटपुट

उपयोगकर्ता इनपुट प्राप्त करने के लिए input() फ़ंक्शन और जानकारी आउटपुट करने के लिए print() फ़ंक्शन का उपयोग करें।

# उपयोगकर्ता इनपुट प्राप्त करना
name = input("कृपया अपना नाम दर्ज करें: ")
age = int(input("कृपया अपनी आयु दर्ज करें: "))

# जानकारी आउटपुट करना
print("स्वागत है", name)
print("आप", age, "वर्ष के हैं")

7.2 स्वरूपित आउटपुट (f-strings)

Python 3.6+ में पेश किए गए, f-strings (स्वरूपित स्ट्रिंग लिटरल्स) स्ट्रिंग्स को स्वरूपित करने का एक सुविधाजनक और शक्तिशाली तरीका है। स्ट्रिंग को f या F के साथ उपसर्ग करें और चर या अभिव्यक्तियों को घुंघराले कोष्ठक {} में शामिल करें।

user = "Alice"
items = 3
total_cost = 45.5

# स्वरूपित संदेश के लिए f-string का उपयोग
message = f"उपयोगकर्ता {user} ने {items} आइटम ${total_cost:.2f} में खरीदे।"
print(message)

# f-strings में अभिव्यक्तियाँ
print(f"2 + 3 बराबर है {2 + 3}")

f-strings में अभिव्यक्तियाँ और फ़ंक्शन कॉल:

width = 10
height = 5

# f-strings में अभिव्यक्तियों का उपयोग
area = f"आयत का क्षेत्रफल: {width * height}"
print(area)

# फ़ंक्शंस को कॉल करना
text = "python"
formatted = f"अपरकेस: {text.upper()}, लंबाई: {len(text)}"
print(formatted)

f-strings में स्वरूपण विकल्प:

pi = 3.14159265359
large_number = 1234567

# संख्या स्वरूपण
print(f"Pi (2 दशमलव): {pi:.2f}")
print(f"Pi (4 दशमलव): {pi:.4f}")
print(f"बड़ा नंबर (हज़ारों में): {large_number:,}")
print(f"प्रतिशत: {0.85:.1%}")

# स्ट्रिंग संरेखण
name = "Python"
print(f"बायाँ संरेखण: '{name:<10}'")
print(f"दायाँ संरेखण: '{name:>10}'")
print(f"केंद्र संरेखण: '{name:^10}'")

f-strings के साथ दिनांक और समय स्वरूपण:

from datetime import datetime

now = datetime.now()
print(f"वर्तमान समय: {now}")
print(f"स्वरूपित समय: {now:%Y-%m-%d %H:%M:%S}")
print(f"केवल दिनांक: {now:%Y-%m-%d}")

9. फ़ंक्शंस

Python में फ़ंक्शंस विशिष्ट कार्यों के लिए पुन: उपयोग योग्य कोड ब्लॉक्स हैं, जिन्हें def कीवर्ड का उपयोग करके परिभाषित किया जाता है, जो डिफ़ॉल्ट पैरामीटर्स, परिवर्तनीय तर्क, और कीवर्ड तर्कों का समर्थन करते हैं।

मूल फ़ंक्शन परिभाषा:

def greet(name):
    """अभिवादन फ़ंक्शन"""
    return f"हैलो, {name}!"

# फ़ंक्शन को कॉल करना
message = greet("John")
print(message)

कीवर्ड तर्क:

कीवर्ड तर्क parameter_name=value सिंटेक्स का उपयोग करके पास किए जाते हैं।

def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

print(greet("Alice"))          # आउटपुट: Hello, Alice!
print(greet("Bob", "Hi"))     # आउटपुट: Hi, Bob!

परिवर्तनीय तर्क:

परिवर्तनीय तर्क फ़ंक्शंस को मनमाने ढंग से तर्क स्वीकार करने की अनुमति देते हैं, या तो स्थिति आधारित (*args) या कीवर्ड आधारित (**kwargs)।

# स्थिति आधारित परिवर्तनीय तर्क (*args)
def sum_numbers(*args):
    return sum(args)

print(sum_numbers(1, 2, 3, 4))  # आउटपुट: 10

# कीवर्ड परिवर्तनीय तर्क (**kwargs)
def print_kwargs(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_kwargs(name="Alice", age=25, city="Beijing")

फ़ंक्शन एनोटेशन्स:

फ़ंक्शन एनोटेशन्स पैरामीटर्स और रिटर्न मानों में वर्णनात्मक मेटाडेटा जोड़ते हैं, जिससे पठनीयता और दस्तावेज़ीकरण में सुधार होता है।

def calculate_area(length: float, width: float) -> float:
    """आयत का क्षेत्रफल गणना करें"""
    return length * width

def process_user(name: str, age: int, active: bool = True) -> dict:
    """उपयोगकर्ता जानकारी प्रोसेस करें"""
    return {
        "name": name,
        "age": age,
        "active": active
    }

10. लैम्ब्डा अभिव्यक्तियाँ

लैम्ब्डा अभिव्यक्तियाँ अनाम फ़ंक्शंस बनाती हैं, जो छोटे फ़ंक्शंस को परिभाषित करने का एक संक्षिप्त तरीका प्रदान करती हैं।

square = lambda x: x ** 2
print(square(5))  # आउटपुट: 25

आमतौर पर map या filter जैसे उच्च-क्रम फ़ंक्शंस के साथ उपयोग की जाती हैं:

numbers = [1, 2, 3, 4]
squares = list(map(lambda x: x ** 2, numbers))
print(squares)  # आउटपुट: [1, 4, 9, 16]

11. क्लासेस और ऑब्जेक्ट्स

Python class कीवर्ड का उपयोग करके ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग का समर्थन करता है:

class Person:
    """Person क्लास"""
    
    def __init__(self, name, age):
        """कंस्ट्रक्टर"""
        self.name = name
        self.age = age
    
    def introduce(self):
        """परिचय विधि"""
        return f"मैं {self.name} हूँ, {self.age} वर्ष का हूँ"
    
    def have_birthday(self):
        """जन्मदिन विधि"""
        self.age += 1
        return f"{self.name} का जन्मदिन था, अब {self.age} वर्ष का है"

# ऑब्जेक्ट्स बनाना
person1 = Person("John", 25)
person2 = Person("Jane", 30)

print(person1.introduce())
print(person2.have_birthday())

11.1 क्लास और इंस्टेंस विशेषताएँ

Python में, क्लास विशेषताएँ और इंस्टेंस विशेषताएँ क्लासेस और ऑब्जेक्ट्स में डेटा संग्रह करने के लिए दो प्रकार की विशेषताएँ हैं।

  • क्लास विशेषताएँ: विधियों के बाहर परिभाषित, क्लास के स्वामित्व में होती हैं, और सभी इंस्टेंसेस में साझा की जाती हैं।
  • इंस्टेंस विशेषताएँ: विधियों में (आमतौर पर __init__ में) परिभाषित, विशिष्ट इंस्टेंसेस से बंधी होती हैं self के माध्यम से।
class Student:
    # क्लास विशेषताएँ
    school = "Stanford University"
    student_count = 0
    
    def __init__(self, name, major):
        # इंस्टेंस विशेषताएँ
        self.name = name
        self.major = major
        Student.student_count += 1
    
    @classmethod
    def get_student_count(cls):
        """क्लास विधि"""
        return cls.student_count
    
    @staticmethod
    def is_valid_age(age):
        """स्थैतिक विधि"""
        return 0 < age < 150

# उपयोग उदाहरण
student1 = Student("John", "Computer Science")
student2 = Student("Jane", "Mathematics")

print(f"स्कूल: {Student.school}")
print(f"कुल छात्र: {Student.get_student_count()}")
print(f"मान्य आयु: {Student.is_valid_age(20)}")

11.2 क्लास इनहेरिटेंस

इनहेरिटेंस एक क्लास (उप-क्लास) को दूसरी क्लास (मूल क्लास) से विशेषताएँ और विधियाँ प्राप्त करने की अनुमति देता है, जिससे कोड का पुन: उपयोग और विस्तार संभव होता है।

class Animal:
    def __init__(self, name, species):
        self.name = name
        self.species = species
    
    def make_sound(self):
        return f"{self.name} एक ध्वनि निकालता है"
    
    def info(self):
        return f"{self.name} एक {self.species} है"

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name, "Dog")
        self.breed = breed
    
    def make_sound(self):
        return f"{self.name} भौंकता है"
    
    def fetch(self):
        return f"{self.name} गेंद लाता है"

class Cat(Animal):
    def __init__(self, name, color):
        super().__init__(name, "Cat")
        self.color = color
    
    def make_sound(self):
        return f"{self.name} म्याऊँ करता है"
    
    def climb(self):
        return f"{self.name} पेड़ पर चढ़ता है"

# इनहेरिटेंस का उपयोग
dog = Dog("Buddy", "Golden Retriever")
cat = Cat("Mimi", "Orange")

print(dog.info())
print(dog.make_sound())
print(dog.fetch())

print(cat.info())
print(cat.make_sound())
print(cat.climb())

11.3 विशेष विधियाँ (मैजिक मेथड्स)

विशेष विधियाँ (या मैजिक मेथड्स) डबल-अंडरस्कोर विधियाँ हैं जो विशिष्ट व्यवहारों को परिभाषित करती हैं, जो Python द्वारा कुछ परिदृश्यों में स्वचालित रूप से कॉल की जाती हैं।

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def __str__(self):
        """स्ट्रिंग प्रतिनिधित्व"""
        return f"Rectangle({self.width}x{self.height})"
    
    def __repr__(self):
        """आधिकारिक स्ट्रिंग प्रतिनिधित्व"""
        return f"Rectangle(width={self.width}, height={self.height})"
    
    def __eq__(self, other):
        """समानता तुलना"""
        if isinstance(other, Rectangle):
            return self.width == other.width and self.height == other.height
        return False
    
    def __lt__(self, other):
        """से कम तुलना (क्षेत्रफल के आधार पर)"""
        if isinstance(other, Rectangle):
            return self.area() < other.area()
        return NotImplemented
    
    def __add__(self, other):
        """जोड़ ऑपरेशन"""
        if isinstance(other, Rectangle):
            return Rectangle(self.width + other.width, self.height + other.height)
        return NotImplemented
    
    def area(self):
        """क्षेत्रफल गणना"""
        return self.width * self.height

# विशेष विधियों का उपयोग
rect1 = Rectangle(3, 4)
rect2 = Rectangle(5, 6)
rect3 = Rectangle(3, 4)

print(rect1)           # Rectangle(3x4)
print(repr(rect1))     # Rectangle(width=3, height=4)
print(rect1 == rect3)  # True
print(rect1 < rect2)   # True
print(rect1 + rect2)   # Rectangle(8x10)

12. संदर्भ प्रबंधक

संदर्भ प्रबंधक संसाधन प्राप्ति और रिलीज़ को सुनिश्चित करते हैं, आमतौर पर with कथन के साथ संसाधन प्रबंधन के लिए उपयोग किए जाते हैं, जैसे फ़ाइलें या डेटाबेस कनेक्शन।

12.1 संदर्भ प्रबंधकों का उपयोग

फ़ाइल ऑपरेशन्स संदर्भ प्रबंधकों का एक सामान्य उपयोग केस हैं:

with open("example.txt", "r") as file:
    content = file.read()
    print(content)

with कथन यह सुनिश्चित करता है कि ऑपरेशन्स के बाद फ़ाइल स्वचालित रूप से बंद हो जाए।

12.2 कस्टम संदर्भ प्रबंधक

__enter__ और __exit__ विधियों को परिभाषित करके कस्टम संदर्भ प्रबंधक बनाएँ:

class DatabaseConnection:
    def __init__(self, database_name):
        self.database_name = database_name
        self.connection = None
    
    def __enter__(self):
        """संदर्भ में प्रवेश करने पर कॉल किया जाता है"""
        print(f"डेटाबेस से कनेक्ट हो रहा है: {self.database_name}")
        self.connection = f"{self.database_name} से कनेक्शन"
        return self.connection
    
    def __exit__(self, exc_type, exc_value, traceback):
        """संदर्भ से बाहर निकलने पर कॉल किया जाता है"""
        print(f"डेटाबेस कनेक्शन बंद हो रहा है: {self.database_name}")
        if exc_type:
            print(f"त्रुटि हुई: {exc_type.__name__}: {exc_value}")
        self.connection = None
        return False  # अपवादों को दबाएँ नहीं

# कस्टम संदर्भ प्रबंधक का उपयोग
with DatabaseConnection("user_database") as conn:
    print(f"कनेक्शन का उपयोग: {conn}")
    print("डेटाबेस ऑपरेशन्स निष्पादित हो रहे हैं...")

contextlib मॉड्यूल का उपयोग करके संदर्भ प्रबंधक बनाना:

from contextlib import contextmanager
import time

@contextmanager
def timer(operation_name):
    """टाइमर संदर्भ प्रबंधक"""
    print(f"{operation_name} शुरू हो रहा है")
    start_time = time.time()
    try:
        yield
    finally:
        end_time = time.time()
        print(f"{operation_name} {end_time - start_time:.2f} सेकंड में पूरा हुआ")

# डेकोरेटर-आधारित संदर्भ प्रबंधक का उपयोग
with timer("डेटा प्रोसेसिंग"):
    # समय-गहन ऑपरेशन का अनुकरण
    time.sleep(1)
    print("डेटा प्रोसेसिंग...")

13. अपवाद प्रबंधन

अपवाद प्रबंधन प्रोग्राम की मजबूती सुनिश्चित करता है, try, except, else, और finally का उपयोग करके अपवादों को प्रबंधित करता है।

try:
    result = 10 / 0
except ZeroDivisionError:
    print("शून्य से विभाजन नहीं कर सकते!")
else:
    print("विभाजन सफल")
finally:
    print("यह हमेशा चलता है")

आउटपुट:

शून्य से विभाजन नहीं कर सकते!
यह हमेशा चलता है

14. फ़ाइल ऑपरेशन्स

Python फ़ाइलों को पढ़ने और लिखने के लिए सरल विधियाँ प्रदान करता है, आमतौर पर संदर्भ प्रबंधकों के साथ उपयोग किया जाता है।

14.1 फ़ाइलें पढ़ना

टेक्स्ट फ़ाइल सामग्री पढ़ना:

with open("example.txt", "r") as file:
    content = file.read()
    print(content)

पंक्ति दर पंक्ति पढ़ना:

with open("example.txt", "r") as file:
    for line in file:
        print(line.strip())

14.2 फ़ाइलें लिखना

टेक्स्ट फ़ाइल में लिखना:

with open("output.txt", "w") as file:
    file.write("हैलो, Python!\n")

सामग्री जोड़ना:

with open("output.txt", "a") as file:
    file.write("नई सामग्री जोड़ना।\n")

15. मॉड्यूल्स और पैकेजेस

मॉड्यूल्स Python कोड वाली फ़ाइलें हैं, और पैकेजेस कई मॉड्यूल्स वाली निर्देशिकाएँ हैं। import का उपयोग करके मॉड्यूल्स आयात करें:

import math
print(math.sqrt(16))  # आउटपुट: 4.0

कस्टम मॉड्यूल उदाहरण (मान लें फ़ाइल का नाम mymodule.py है):

# mymodule.py
def say_hello():
    return "मॉड्यूल से हैलो!"

आयात और उपयोग:

import mymodule
print(mymodule.say_hello())  # आउटपुट: मॉड्यूल से हैलो!

16. स्कोप और नेमस्पेस

16.1 स्कोप

स्कोप उस क्षेत्र को परिभाषित करता है जहाँ एक वेरिएबल सुलभ है। Python वेरिएबल लुकअप के लिए LEGB नियम का पालन करता है:

  • L (स्थानीय): फ़ंक्शन या क्लास विधि के अंदर।
  • E (संलग्न): नेस्टेड फ़ंक्शन (क्लोजर) के बाहरी फ़ंक्शन में।
  • G (वैश्विक): मॉड्यूल स्तर पर।
  • B (अंतर्निहित): अंतर्निहित फ़ंक्शंस और अपवाद जैसे print() या len()
x = "वैश्विक x"

def outer_func():
    x = "संलग्न x"
    def inner_func():
        x = "स्थानीय x"
        print(x) # स्थानीय स्कोप x तक पहुँचता है
    inner_func()
    print(x) # संलग्न स्कोप x तक पहुँचता है

outer_func()
print(x) # वैश्विक स्कोप x तक पहुँचता है

स्कोप वेरिएबल्स को संशोधित करने के लिए global या nonlocal का उपयोग:

x = "वैश्विक"
def modify_global():
    global x
    x = "संशोधित"
modify_global()
print(x)  # आउटपुट: संशोधित

16.2 नेमस्पेस

नेमस्पेस नामों से ऑब्जेक्ट्स तक का मैपिंग है, जैसे एक डिक्शनरी जिसमें कुंजियाँ वेरिएबल नाम हैं और मान ऑब्जेक्ट्स हैं।

प्रत्येक मॉड्यूल, फ़ंक्शन, और क्लास का अपना नेमस्पेस होता है, जो नामकरण संघर्षों को रोकता है। नेमस्पेस का निरीक्षण करने के लिए globals() और locals() का उपयोग करें।

a_variable = 10

def some_function():
    b_variable = 20
    # locals() वर्तमान स्थानीय नेमस्पेस डिक्शनरी लौटाता है
    print(f"स्थानीय: {locals()}")

print(f"वैश्विक: {globals().keys()}") # वैश्विक नेमस्पेस की कुंजियाँ प्रिंट करता है
some_function()

17. जेनरेटर्स

जेनरेटर्स विशेष इटेरेटर्स हैं जो मांग पर मान उत्पन्न करते हैं, न कि एक बार में सभी मान बनाते हैं, जिससे वे बड़े डेटासेट्स के लिए मेमोरी-कुशल बनते हैं।

जेनरेटर्स yield कीवर्ड का उपयोग करके मान लेज़ीली लौटाते हैं:

def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

for num in fibonacci(5):
    print(num)  # आउटपुट: 0, 1, 1, 2, 3

18. मल्टीथ्रेडिंग

मल्टीथ्रेडिंग एक प्रोग्राम को कई ऑपरेशन्स समवर्ती रूप से निष्पादित करने की अनुमति देता है, जो I/O-बाउंड कार्यों जैसे नेटवर्क अनुरोधों या फ़ाइल ऑपरेशन्स के लिए उपयोगी है।

Python का threading मॉड्यूल थ्रेड्स बनाने और प्रबंधित करने के लिए उपकरण प्रदान करता है। ग्लोबल इंटरप्रेटर लॉक (GIL) के कारण, मल्टीथ्रेडिंग एकल प्रक्रिया में सच्चा CPU समानांतरवाद प्राप्त नहीं करता, लेकिन यह I/O-बाउंड कार्यों के लिए प्रदर्शन में काफी सुधार करता है।

import threading
import time

def worker(thread_name):
    print(f"थ्रेड {thread_name} शुरू हो रहा है...")
    time.sleep(2) # समय-गहन ऑपरेशन का अनुकरण
    print(f"थ्रेड {thread_name} समाप्त हुआ।")

# थ्रेड्स बनाएँ
thread1 = threading.Thread(target=worker, args=("A",))
thread2 = threading.Thread(target=worker, args=("B",))

# थ्रेड्स शुरू करें
thread1.start()
thread2.start()

# सभी थ्रेड्स के पूरा होने की प्रतीक्षा करें
thread1.join()
thread2.join()

print("सभी थ्रेड्स पूरे हुए।")

19. एसिंक्रोनस प्रोग्रामिंग

एसिंक्रोनस प्रोग्रामिंग उच्च I/O, उच्च-समानता परिदृश्यों के लिए आदर्श है, जो थ्रेड्स के बजाय एक इवेंट लूप का उपयोग करके कार्यों को प्रबंधित करता है।

Python asyncio लाइब्रेरी और async/await सिंटेक्स के माध्यम से एसिंक्रोनस प्रोग्रामिंग का समर्थन करता है।

  • async def: एक कोरटीन को परिभाषित करता है।
  • await: कोरटीन निष्पादन को रोकता है, एक प्रतीक्षायोग्य ऑब्जेक्ट के पूरा होने की प्रतीक्षा करता है।
import asyncio

async def say_hello():
    print("हैलो")
    await asyncio.sleep(1) # गैर-अवरोधक नींद, I/O का अनुकरण
    print("वर्ल्ड")

async def main():
    # एक कार्य बनाएँ और प्रतीक्षा करें
    await asyncio.create_task(say_hello())

# मुख्य कोरटीन चलाएँ
asyncio.run(main())

आउटपुट:

हैलो
वर्ल्ड